import React, { PureComponent } from 'react';
import classnames from 'classnames';
import styles from './style.module';

const addIcon = require('./add.svg');
const cutIcon = require('./cut.svg');

class Stepper extends PureComponent {
    static defaultProps = {
        value: null,
        step: 1,
        min: 1,
        max: null,
        onFocus: () => {},
        onChange: () => {},
        onBlur: () => {},
        onButtonClick: () => {},
        disabled: false
    };

    // 存储高度，用于判读是否需要滑动视图
    scroll = document.documentElement.clientHeight;

    constructor(props) {
        super(props);

        const value = props.value || props.min || 1;

        this.state = {
            num: value,
            disableAddButton: Boolean(props.max && value === props.max),
            disableCutButton: value === props.min
        };

        this.fnum = ('' + this.props.step).replace(/^\d+\./, '.');

        this.add = this.add.bind(this);
        this.cut = this.cut.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleFocus = this.handleFocus.bind(this);
        this.handleBlur = this.handleBlur.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        if (this.props !== nextProps && nextProps.value) {
            this.setState({
                num: nextProps.value,
                disableAddButton: nextProps.value >= nextProps.max,
                disableCutButton: nextProps.value <= nextProps.min
            });
        }
    }

    /**
     * 增加数量
     */
    add(e) {
        e.stopPropagation();
        const { step = 1, max, value, onButtonClick } = this.props;
        const { num } = this.state;
        const showValue = (Number(num) + Number(step)).toFixed(
            this.fnum.length - 1
        );
        if (max <= showValue) {
            this.setState({
                disableAddButton: true
            });
            return;
        }

        if (showValue <= max) {
            this.setState({
                num: showValue,
                disableAddButton: showValue === max,
                disableCutButton: false
            });
        }

        onButtonClick && onButtonClick(showValue);
    }

    /**
     * 删除数量
     */
    cut(e) {
        e.stopPropagation();
        const { min = 1, step = 1, value, onButtonClick } = this.props;
        const { num } = this.state;
        const showValue = (Number(num) - Number(step)).toFixed(
            this.fnum.length - 1
        );
        if (min >= showValue) {
            this.setState({
                disableCutButton: true
            });
            return;
        }

        if (showValue >= min) {
            this.setState({
                num: showValue,
                disableAddButton: false,
                disableCutButton: showValue === min
            });
        }

        onButtonClick && onButtonClick(showValue);
    }

    /**
     * input变化
     *
     * @param {object} e 事件对象
     */
    handleChange(e) {
        const { onChange } = this.props;
        const val = parseInt(e.currentTarget.value, 10);

        this.setState({
            num: val
        });

        onChange && onChange(val);
    }

    handleFocus(e) {
        e.stopPropagation();
        e.preventDefault();

        const u = navigator.userAgent;
        const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
        // 解决安卓输入页面未上滑
        if (isAndroid) {
            const interval = setInterval(() => {
                if (document.documentElement.clientHeight !== this.scroll) {
                    this.stepperRef.scrollIntoViewIfNeeded();
                    clearInterval(interval);
                }
            }, 100);
        }

        this.props.onFocus && this.props.onFocus();
    }

    /**
     * input失去焦点
     *
     * @param {object} e 事件对象
     */
    handleBlur(e) {
        const { onBlur, max, min = 1 } = this.props;
        const val = parseInt(e.currentTarget.value, 10);

        let showValue = val;

        if (max && val >= max) {
            showValue = max;
        }

        if (val < min || !showValue) {
            showValue = min;
        }

        if (!this.props.value) {
            this.setState({
                num: showValue,
                disableAddButton: showValue === this.props.max,
                disableCutButton: showValue === this.props.min
            });
        }

        onBlur && onBlur(showValue);
    }

    render() {
        const { num, disableAddButton, disableCutButton } = this.state;
        const { disabled } = this.props;

        return (
            <div
                className={styles.Stepper}
                ref={ref => {
                    this.stepperRef = ref;
                }}
            >
                <div
                    className={classnames(
                        styles.StepperButton,
                        styles.StepperCut,
                        { [styles.disable]: disableCutButton || disabled }
                    )}
                    onClick={!disabled ? this.cut : undefined}
                >
                    <img className={styles.StepperIcon} src={cutIcon} />
                </div>
                <div className={styles.StepperPut}>
                    <input
                        disabled={disabled}
                        onChange={this.handleChange}
                        onBlur={this.handleBlur}
                        onFocus={this.handleFocus}
                        onClick={this.handleFocus}
                        value={num}
                        type="number"
                        readOnly={true}
                    />
                </div>
                <div
                    className={classnames(
                        styles.StepperButton,
                        styles.StepperAdd,
                        { [styles.disable]: disableAddButton || disabled }
                    )}
                    onClick={!disabled ? this.add : undefined}
                >
                    <img className={styles.StepperIcon} src={addIcon} />
                </div>
            </div>
        );
    }
}

export default Stepper;
